
import os

from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QDockWidget
import PyQt5.QtWidgets as QW_
from PyQt5 import QtCore
from PyQt5 import QtGui

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtQuickWidgets import *
from PyQt5.QtWebEngineWidgets import *

import json
# 记录父节点与子节点添加关系函数

from QSubWidgets import *


context_menus = []



class NContextMenu:
    def __init__(self):
        self.menus = []
        self.menu = QW_.QMenu()
        self.widget_ = None

    def setWidget(self, widget):
        self.widget_ = widget

    def addMenu(self, menu):
        self.menus.append(menu)
        self.menu.addMenu(menu)

    def setObjectName(self, name):
        pass

    def showMenu(self, pos):
        self.menu.exec_(self.widget_.viewport().mapToGlobal(pos))

class NQFormLayoutRow:
    def __init__(self):
        self._children = []
        self._label = ''
    def setLabel(self, label):
        self._label = label
    def addChild(self, widget):
        self._children.append(widget)
        

def add_context_menu(config, parent, child):
    global context_menus
    context_menus.append(child)

    child.setWidget(parent)
    parent.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    parent.customContextMenuRequested.connect(child.showMenu)

def add_invalid(config, parent, child):
    print("Invlid child:", child)
    pass

def add_formlayout_row(config, parent, child):
    if len(child._children)>1:
        parent.addRow(child._children[0], child._children[1])
    elif len(child._children) == 1:
        parent.addRow(config['properties']['NQFormLayoutRow::Label'], child._children[0])
    else:
        print("QFromlayoutRow must have least one child!")


def add_dock_widget(config, parent, child):
    prop_dock_area = config['pos']['POS::DockWidgetArea']
    dock_area = eval('QtCore.Qt.'+prop_dock_area+'DockWidgetArea')
    parent.addDockWidget(dock_area, child)

    '''
                if 'add_info' in child and 'DockWidgetArea' in child['add_info']:
                    dock_area_set = child['add_info']['DockWidgetArea']
                    if dock_area_set == "LeftDockWidgetArea":
                        dock_area = QtCore.Qt.LeftDockWidgetArea
                    elif dock_area_set == "RightDockWidgetArea":
                        dock_area = QtCore.Qt.RightDockWidgetArea
                    elif dock_area_set == "TopDockWidgetArea":
                        dock_area = QtCore.Qt.TopDockWidgetArea
                    elif dock_area_set == "BottomDockWidgetArea":
                        dock_area = QtCore.Qt.BottomDockWidgetArea
                    elif dock_area_set == "AllDockWidgetAreas":
                        dock_area = QtCore.Qt.AllDockWidgetAreas
                    elif dock_area_set == "NoDockWidgetArea":
                        dock_area = QtCore.Qt.NoDockWidgetArea

                win.addDockWidget(dock_area, child_)
    '''



def add_tab(config, parent, child):
    tab_name = 'tab'
    if 'pos' in config and 'POS::TabName' in config['pos']:
        tab_name = config['pos']['POS::TabName']
    parent.addTab(child, tab_name)

def add_toolbar_item(config, parent, child):
    if 'NToolBarItem::Icon' in config['properties']:
        parent.addAction(QtGui.QIcon(config['properties']['NToolBarItem::Icon']), child)
    else:
        parent.addAction(child)

def add_toolbarSeparator(config, parent, child):
    parent.addSeparator()

def add_gridlayout_item(config, parent, child):
    parent.addWidget(child, int(config['pos']['POS::row']), int(config['pos']['POS::col']), int(config['pos']['POS::rowspan']), int(config['pos']['POS::colspan']))

def add_view_cell_item(config, parent, child):
    row = config['pos']['POS::row']
    col = config['pos']['POS::col']
    row = int(row)
    col = int(col)
    parent.setIndexWidget(parent.model().index(row, col), child)

    

controls = {
'QAbstractButton' : {
    'parent': 'QWidget',
    'properties':{
        'Text': {
            'type': 'String',
            'default': 'MyButton'
        },
        'Icon': {
            'type': 'QIcon',
            'default': ''
        },
        
    }
},
'QAbstractGraphicsShapeItem' : {
    'parent': 'QGraphicsItem',
    'properties':{
        
    }
},
'QAbstractItemDelegate' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QAbstractItemView' : {
    'parent': 'QAbstractScrollArea',
    'properties':{
        
    }
},
'QAbstractScrollArea' : {
    'parent': 'QFrame',
    'properties':{
        
    }
},
'QAbstractSlider' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QAbstractSpinBox' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QAccessibleWidget' : {
    'parent': 'QAccessibleObject',
    'properties':{
        
    }
},
'QAction' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QActionGroup' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QApplication' : {
    'parent': 'QGuiApplication',
    'properties':{
        
    }
},
'QBoxLayout' : {
    'parent': 'QLayout'
},
'QButtonGroup' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QCalendarWidget' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QCheckBox' : {
    'parent': 'QAbstractButton',
    'properties':{
        
    }
},
'QColorDialog' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QColormap' : {
    'properties':{
        
    }
},
'QColumnView' : {
    'parent': 'QAbstractItemView',
    'properties':{
        
    }
},
'QComboBox' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QCommandLinkButton' : {
    'parent': 'QAbstractButton',
    'properties':{
        
    }
},
'QCommonStyle' : {
    'parent': 'QStyle',
    'properties':{
        
    }
},
'QCompleter' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'NContextMenu': {},
'QDataWidgetMapper' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QDateEdit' : {
    'parent': 'QDateTimeEdit',
    'properties':{
        
    }
},
'QDateTimeEdit' : {
    'parent': 'QAbstractSpinBox',
    'properties':{
        
    }
},
'QDesktopWidget' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QDial' : {
    'parent': 'QAbstractSlider',
    'properties':{
        
    }
},
'QDialog' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QDialogButtonBox' : {
    'parent': '',
    'properties':{
        
    }
},
'QDirModel' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QDockWidget' : {
    'parent': 'QWidget',
    'properties': {
        'WindowTitle': {
            'type': 'String',
            'default': 'dock'
        },
        
    }
},
'QDoubleSpinBox' : {
    'parent': 'QAbstractSpinBox',
    'properties':{
        
    }
},
'QErrorMessage' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QFileDialog' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QFileIconProvider' : {
    'parent': '',
    'properties':{
        
    }
},
'QFileSystemModel' : {
    'parent': 'QAbstractItemModel',
    'properties':{
        
    }
},
'QFocusFrame' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QFontComboBox' : {
    'parent': 'QComboBox',
    'properties':{
        
    }
},
'QFontDialog' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QFormLayout' : {
    'parent': 'QLayout',
},
'NQFormLayoutRow': {
    'parent': '',
    'properties':{
        'Label': {
            'type': 'String',
            'default': 'label'
        }
    }
},
'QFrame' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QGesture' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QGestureEvent' : {
    'parent': 'QEvent',
    'properties':{
        
    }
},
'QGestureRecognizer' : {
    'parent': '',
    'properties':{
        
    }
},
'QGraphicsAnchor' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QGraphicsAnchorLayout' : {
    'parent': 'QGraphicsLayout',
},
'QGraphicsBlurEffect' : {
    'parent': 'QGraphicsEffect',
    'properties':{
        
    }
},
'QGraphicsColorizeEffect' : {
    'parent': 'QGraphicsEffect',
    'properties':{
        
    }
},
'QGraphicsDropShadowEffect' : {
    'parent': 'QGraphicsEffect',
    'properties':{
        
    }
},
'QGraphicsEffect' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QGraphicsEllipseItem' : {
    'parent': 'QAbstractGraphicsShapeItem',
    'properties':{
        
    }
},
'QGraphicsGridLayout' : {
    'parent': 'QGraphicsLayout',
},
'QGraphicsItem' : {
    'parent': '',
    'properties':{
        
    }
},
'QGraphicsItemAnimation' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QGraphicsItemGroup' : {
    'parent': 'QGraphicsItem',
    'properties':{
        
    }
},
'QGraphicsLayout' : {
    'parent': 'QGraphicsLayoutItem',
},
'QGraphicsLayoutItem' : {
    'parent': '',
},
'QGraphicsLineItem' : {
    'parent': 'QGraphicsItem',
    'properties':{
        
    }
},
'QGraphicsLinearLayout' : {
    'parent': 'QGraphicsLayout',
},
'QGraphicsObject' : {
    'parent': 'QGraphicsItem',
    'properties':{
        
    }
},
'QGraphicsOpacityEffect' : {
    'parent': 'QGraphicsEffect',
    'properties':{
        
    }
},
'QGraphicsPathItem' : {
    'parent': 'QAbstractGraphicsShapeItem',
    'properties':{
        
    }
},
'QGraphicsPixmapItem' : {
    'parent': 'QGraphicsItem',
    'properties':{
        
    }
},
'QGraphicsPolygonItem' : {
    'parent': 'QAbstractGraphicsShapeItem',
    'properties':{
        
    }
},
'QGraphicsProxyWidget' : {
    'parent': 'QGraphicsWidget',
    'properties':{
        
    }
},
'QGraphicsRectItem' : {
    'parent': 'QAbstractGraphicsShapeItem',
    'properties':{
        
    }
},
'QGraphicsRotation' : {
    'parent': 'QGraphicsTransform',
    'properties':{
        
    }
},
'QGraphicsScale' : {
    'parent': 'QGraphicsTransform',
    'properties':{
        
    }
},
'QGraphicsScene' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QGraphicsSceneContextMenuEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneDragDropEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneEvent' : {
    'parent': 'QEvent',
    'properties':{
        
    }
},
'QGraphicsSceneHelpEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneHoverEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneMouseEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneMoveEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneResizeEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSceneWheelEvent' : {
    'parent': 'QGraphicsSceneEvent',
    'properties':{
        
    }
},
'QGraphicsSimpleTextItem' : {
    'parent': 'QAbstractGraphicsShapeItem',
    'properties':{
        
    }
},
'QGraphicsTextItem' : {
    'parent': 'QGraphicsObject',
    'properties':{
        
    }
},
'QGraphicsTransform' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QGraphicsView' : {
    'parent': 'QAbstractScrollArea',
    'properties':{
        
    }
},
'QGraphicsWidget' : {
    'parent': 'QGraphicsObject',
    'properties':{
        
    }
},
'QGridLayout' : {
    'parent': 'QLayout'
},
'QGroupBox' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QHBoxLayout' : {
    'parent': 'QBoxLayout'
},
'QHeaderView' : {
    'parent': 'QAbstractItemView',
    'properties':{
        
    }
},
'EQHLine': {
    'parent': 'QFrame'
},
'QInputDialog' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QItemDelegate' : {
    'parent': 'QAbstractItemDelegate',
    'properties':{
        
    }
},
'QItemEditorCreatorBase' : {
    'parent': '',
    'properties':{
        
    }
},
'QItemEditorFactory' : {
    'parent': '',
    'properties':{
        
    }
},
'QKeyEventTransition' : {
    'parent': 'QEventTransition',
    'properties':{
        
    }
},
'QKeySequenceEdit' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QLCDNumber' : {
    'parent': 'QFrame',
    'properties':{
        
    }
},
'QLabel' : {
    'parent': 'QFrame',
    'properties':{
        'Text': {
            'type': 'String',
            'default': 'MyLabel'
        },
        'Pixmap': {
            'type': 'QPixmap',
            'default': ''
        },
        
    }
},
'QLayout' : {
    'parent': 'QObject',
    'properties': {
        'ContentsMargins': {
            'type': 'QMargins',
            'default': '0,0,0,0'
        },
        'Spacing': {
            'type': 'Number',
            'default': '0'
        }
    }
},
'QLayoutItem' : {
    'parent': ''
},
'QLineEdit' : {
    'parent': 'QWidget',
    'properties':{
        'PlaceholderText': {
            'type': 'String',
            'default': ''
        }
    }
},
'QListView' : {
    'parent': 'QAbstractItemView',
    'properties':{
        
    }
},
'QListWidget' : {
    'parent': 'QListView',
    'properties':{
        
    }
},
'QListWidgetItem' : {
    'parent': '',
    'properties':{
        
    }
},
'QMainWindow' : {
    'parent': 'QWidget',
    'properties': {
        'WindowTitle': {
            'type': 'String',
            'default': 'window'
        },
        
    }
},
'QMdiArea' : {
    'parent': 'QAbstractScrollArea',
    'properties':{
        
    }
},
'QMdiSubWindow' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QMenu' : {
    'parent': 'QWidget',
    'properties': {
        'Title': {
            'type': 'String',
            'default': 'Menu'
        },
        
    }
},
'QMenuBar' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QMessageBox' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QMouseEventTransition' : {
    'parent': 'QEventTransition',
    'properties':{
        
    }
},
'QOpenGLWidget' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QPanGesture' : {
    'parent': 'QGesture',
    'properties':{
        
    }
},
'QPinchGesture' : {
    'parent': 'QGesture',
    'properties':{
        
    }
},
'QPlainTextDocumentLayout' : {
    'parent': 'QAbstractTextDocumentLayout'
},
'QPlainTextEdit' : {
    'parent': 'QAbstractScrollArea',
    'properties':{
        
    }
},
'QProgressBar' : {
    'parent': 'QWidget'
    #'properties':{
    #    'TextVisible': {
    #        'type': 'Bool',
    #        'default': True
    #    },
    #    'Value': {
    #        'type': 'Number',
    #        'default': 70
    #    }
    #}
},
'QProgressDialog' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QProxyStyle' : {
    'parent': 'QCommonStyle',
    'properties':{
        
    }
},
'QPushButton' : {
    'parent': 'QAbstractButton',
    'properties':{
        
    }
},
'QQuickWidget': {
    'parent': 'QWidget',
    'properties' : {
        'Source': {
            'type': 'QUrl',
            'default': ''
        }
    }
},
'QRadioButton': {
    'parent': 'QAbstractButton',
    'properties':{
        
    }
},
'QRubberBand' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QScrollArea' : {
    'parent': 'QAbstractScrollArea',
    'properties':{
        
    }
},
'QScrollBar' : {
    'parent': 'QAbstractSlider',
    'properties':{
        
    }
},
'QScroller' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QScrollerProperties' : {
    'parent': '',
    'properties':{
        
    }
},
'QShortcut' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QSizeGrip' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QSizePolicy' : {
    'parent': '',
    'properties':{
        
    }
},
'QSlider' : {
    'parent': 'QAbstractSlider',
    'properties':{
        
    }
},
'NSpace': {
    'parent': '',
    'properties': {
        'Size': {
            'type': 'Number',
            'default': '10'
        }
    }
},
'QSpacerItem' : {
    'parent': 'QLayoutItem',
    'properties':{
        
    }
},
'QSpinBox' : {
    'parent': 'QAbstractSpinBox',
    'properties':{
        
    }
},
'QSplashScreen' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QSplitter' : {
    'parent': 'QFrame',
    'properties':{
        'Orientation': {
            'type': 'Orientation',
            'default': '0'
        }
    }
},
'QSplitterHandle' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QStackedLayout' : {
    'parent': 'QLayout'
},
'QStackedWidget' : {
    'parent': 'QFrame',
    'properties':{
        
    }
},
'QStatusBar' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'NStretch': {
    'parent': '',
    'properties': {
        'Stretch': {
            'type': 'Number',
            'default': '1'
        }
    }
},
'QStyle' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QStyleFactory' : {
    'parent': '',
    'properties':{
        
    }
},
'QStyleHintReturn' : {
    'parent': '',
    'properties':{
        
    }
},
'QStyleHintReturnMask' : {
    'parent': 'QStyleHintReturn',
    'properties':{
        
    }
},
'QStyleHintReturnVariant' : {
    'parent': 'QStyleHintReturn',
    'properties':{
        
    }
},
'QStyleOption' : {
    'parent': '',
    'properties':{
        
    }
},
'QStyleOptionButton' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionComboBox' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionComplex' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionDockWidget' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionFocusRect' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionFrame' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionGraphicsItem' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionGroupBox' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionHeader' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionMenuItem' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionProgressBar' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionRubberBand' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionSizeGrip' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionSlider' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionSpinBox' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionTab' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionTabBarBase' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionTabWidgetFrame' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionTitleBar' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionToolBar' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionToolBox' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStyleOptionToolButton' : {
    'parent': 'QStyleOptionComplex',
    'properties':{
        
    }
},
'QStyleOptionViewItem' : {
    'parent': 'QStyleOption',
    'properties':{
        
    }
},
'QStylePainter' : {
    'parent': 'QPainter',
    'properties':{
        
    }
},
'QStyledItemDelegate' : {
    'parent': 'QAbstractItemDelegate',
    'properties':{
        
    }
},
'QSwipeGesture' : {
    'parent': 'QGesture',
    'properties':{
        
    }
},
'QSystemTrayIcon' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QTabBar' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QTabWidget' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'QTableView' : {
    'parent': 'QAbstractItemView',
    'properties':{
        
    }
},
'QTableWidget' : {
    'parent': 'QTableView',
    'properties':{
        
    }
},
'QTableWidgetItem' : {
    'parent': '',
    'properties':{
        
    }
},
'QTableWidgetSelectionRange' : {
    'parent': '',
    'properties':{
        
    }
},
'QTapAndHoldGesture' : {
    'parent': 'QGesture',
    'properties':{
        
    }
},
'QTapGesture' : {
    'parent': 'QGesture',
    'properties':{
        
    }
},
'QTextBrowser' : {
    'parent': 'QTextEdit',
    'properties':{
        
    }
},
'QTextEdit' : {
    'parent': 'QAbstractScrollArea',
    'properties':{
        
    }
},
'QTileRules' : {
    'parent': '',
    'properties':{
        
    }
},
'QTimeEdit' : {
    'parent': 'QDateTimeEdit',
    'properties':{
        
    }
},
'QToolBar' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
'NToolBarItem': {
    'properties':{
        'Text': {
            'type': 'String',
            'default': 'Button'
        },
        'Icon': {
            'type': 'String',
            'default': ''
        }
    }
},
'NToolBarSeparator': {
    'properties':{
        
    }
},
'QToolBox' : {
    'parent': 'QFrame',
    'properties':{
        
    }
},
'QToolButton' : {
    'parent': 'QAbstractButton',
    'properties':{
        
    }
},
'QToolTip' : {
    'parent': '',
    'properties':{
        
    }
},
'QTreeView' : {
    'parent': 'QAbstractItemView',
    'properties':{
        
    }
},
'QTreeWidget' : {
    'parent': 'QTreeView',
    'properties':{
        
    }
},
'QTreeWidgetItem' : {
    'parent': '',
    'properties':{
        
    }
},
'QTreeWidgetItemIterator' : {
    'parent': '',
    'properties':{
        
    }
},
'QUndoCommand' : {
    'parent': '',
    'properties':{
        
    }
},
'QUndoGroup' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QUndoStack' : {
    'parent': 'QObject',
    'properties':{
        
    }
},
'QUndoView' : {
    'parent': 'QListView',
    'properties':{
        
    }
},
'QVBoxLayout' : {
    'parent': 'QBoxLayout'
},
'EQVLine': {
    'parent': 'QFrame'
},
'QWebEngineView': {
    'parent': 'QWidget',
    'properties': {
        'Url': {
            'type': 'QUrl',
            'default': ''
        }
    }
},
'QWhatsThis' : {
    'parent': '',
    'properties':{
        
    }
},
'QObject': {
    'parent': '',
    'properties': {
        'ObjectName': {
            'type': 'String',
            'default': ''
        }
    }
},
'QWidget' : {
    'parent': 'QObject',
    'properties':{
        'ToolTip': {
            'type': 'String',
            'default': ''
        },
        'StyleSheet': {
            'type': 'FileContent',
            'default': ''
        },
        'MaximumHeight': {
            'type': 'Number',
            'default': ''
        },
        'MaximumWidth': {
            'type': 'Number',
            'default': ''
        },
        'MinimumHeight': {
            'type': 'Number',
            'default': ''
        },
        'MinimumWidth': {
            'type': 'Number',
            'default': ''
        },
        'ContentsMargins': {
            'type': 'QMargins',
            'default': ''
        }
    }
},
'QWidgetAction' : {
    'parent': 'QAction',
    'properties':{
        
    }
},
'QWidgetItem' : {
    'parent': 'QLayoutItem',
    'properties':{
        
    }
},
'QWizard' : {
    'parent': 'QDialog',
    'properties':{
        
    }
},
'QWizardPage   ' : {
    'parent': 'QWidget',
    'properties':{
        
    }
},
}


child_methods = {
    'default': {
        'default': 'addWidget',
        'QVBoxLayout': 'setLayout',
        'QHBoxLayout': 'setLayout',
        'QFormLayout': 'setLayout',
        'QGridLayout': 'setLayout',
        'NContextMenu': add_context_menu,
        'NQFormLayoutRow': add_invalid
    },
    'NContextMenu': {
        'QMenu': 'addMenu'
    },
    'QMainWindow': {
        'default': 'setCentralWidget',
        'QMenuBar': 'setMenuBar',
        'QToolBar': 'addToolBar',
        'QDockWidget': add_dock_widget
    },
    'QFormLayout': {
        'default': 'addRow',
        'NQFormLayoutRow': add_formlayout_row
    },
    'NQFormLayoutRow': {
        'default': 'addChild'
    },
    'QMenuBar': {
        'default': 'addMenu'
    },
    'QMenu': {
        'default': 'addMenu'
    },
    'QToolBar': {
        'default': 'addWidget',
        'NToolBarItem': add_toolbar_item, #'addAction',
        'NToolBarSeparator': add_toolbarSeparator
    },
    'QTabWidget': {
        'default': add_tab
    },
    'QDockWidget': {
        'default': 'setWidget'
    },
    'QHBoxLayout': {
        'NSpace': 'addSpacing',
        'NStretch': 'addStretch',
        'QHBoxLayout': 'addLayout',
        'QVBoxLayout': 'addLayout',
        'QFormLayout': 'addLayout'
    },
    'QVBoxLayout': {
        'NSpace': 'addSpacing',
        'NStretch': 'addStretch',
        'QHBoxLayout': 'addLayout',
        'QVBoxLayout': 'addLayout',
        'QFormLayout': 'addLayout'
    },
    'QGridLayout': {
        'default': add_gridlayout_item
    },
    'QTableView': {
        'default': add_view_cell_item
    },
    'QTreeView': {
        'default': add_view_cell_item
    },
    'QListView': {
        'default': add_view_cell_item
    },
    'QHeaderView': {
        'default': add_view_cell_item
    },
    'QUndoView': {
        'default': add_view_cell_item
    },
    'QColumnView': {
        'default': add_view_cell_item
    },
    'QScrollArea': {
        'default': 'setWidget'
    },
    'QMdiArea': {
        'default': 'addSubWindow'
    }
}


def to_standardItemModel(data):
    # header
    data_v = json.loads(data)
    cols = len(data_v[0])
    
    model = QtGui.QStandardItemModel(0, cols)
    for i in range(0,cols):
        model.setHeaderData(i, QtCore.Qt.Horizontal, data_v[0][i])

    # data
    # - 表示子层
    # 例如：
    # [2,3,4],[-21, 31, 41],[-21, 31, 41]
    last_items = []
    last_items.append({'l': -1, 'item': model})

    for i in range(1, len(data_v)):
        # 获取缩进标记
        level = 0
        text = data_v[i][0]

        for k in range(0, len(text)):
            #print(text[k:k+1])
            if text[k:k+1] == '-':
                level = k+1
            else:
                break

        parent_level = level-1
        #print('level:', level, '  parent:', parent_level)
        #print(last_items)
        while True:
            parent = last_items[-1]
            if parent['l'] > parent_level:
                last_items.pop()
            else:
                break
        
        # 构建QStandardItem
        list_item = []
        for j in range(0, len(data_v[i])):
            list_item.append(QtGui.QStandardItem(data_v[i][j]))
        
        #print('parent:', parent['item'])
        #print('child', list_item[0])
        parent['item'].appendRow(list_item)

        last_items.append({'l': level, 'item': list_item[0]})

    return model

menus = []
def create_QMenu(config):
    menu = QW_.QMenu()

    if 'data' in config and 'Data::Icon' in config['data']:
        menu.setIcon(QtGui.QIcon(config['data']['Data::Icon']))

    menus.append(menu)
    return menu

def create_toolbarItem(config):
    return config['properties']['NToolBarItem::Text']

def create_toolbarSeparator(config):
    return ""

def create_context_menu(config):
    menu_obj = NContextMenu()
    return menu_obj

def create_nsapce(config):
    return int(config['properties']['NSpace::Size'])

def create_nstretch(config):
    return int(config['properties']['NStretch::Stretch'])

def create_formlayoutrow(config):
    return NQFormLayoutRow()

def create_QQuickWidget(config):
    return QQuickWidget()

def create_QWebEngineView(config):
    return QWebEngineView()

def create_EQVLine(config):
    line = QFrame()
    line.setFrameShape(QFrame.HLine)
    line.setFrameShadow(QFrame.Sunken)

    return line

def create_EQHLine(config):
    line = QFrame()
    line.setFrameShape(QFrame.HLine)
    line.setFrameShadow(QFrame.Sunken)

    return line

create_method = {
    'QMenu': create_QMenu,
    'NToolBarItem': create_toolbarItem,
    'NToolBarSeparator': create_toolbarSeparator,
    'NContextMenu': create_context_menu,
    'NSpace' : create_nsapce,
    'NStretch': create_nstretch,
    'NQFormLayoutRow': create_formlayoutrow,
    'QQuickWidget': create_QQuickWidget,
    'QWebEngineView': create_QWebEngineView,
    'EQVLine': create_EQVLine,
    'EQHLine': create_EQHLine
}


def is_layout(config):
    widget = config['widget']
    if widget == 'QVBoxLayout':
        return True
    elif widget == 'QHBoxLayout':
        return True
    elif widget == 'QFormLayout':
        return True
    elif widget == 'QGridLayout':
        return True

    return False

'''
def openMenu(position):
    menu = QW_.QMenu()
    quitAction = menu.addAction("Quit")
    quitAction = menu.addAction("Quit2")
    quitAction = menu.addAction("Quit3")
    quitAction = menu.addAction("Quit4")
    quitAction = menu.addAction("Quit5")
    quitAction = menu.addAction("Quit6")
    menu.exec_(position)
'''
def get_properties(widget_class):
    props = {}
    if widget_class != "" and widget_class in controls:
        if 'properties' in controls[widget_class]:
            properties = controls[widget_class]['properties']
            for pro in properties:
                props[widget_class+"::"+pro] = properties[pro]
            
        # parent
        if 'parent' in controls[widget_class]:
            prop_par = get_properties(controls[widget_class]['parent'])
            for pro in prop_par:
                props[pro] = prop_par[pro]
    return props
def makeui(config, node2widget):
    if 'widget' not in config:
        return None

    widget = config['widget']

    try:
        if widget in create_method:
            widget_ = create_method[widget](config)
        else:
            #widget_ = eval('QW_.'+widget+'()')            
            widget_ = eval('C'+widget+'()')
    except:
        return None
        
    #print('widget:', widget, widget_)
    if is_layout(config) == False and type(widget_) != type('') and widget != "NContextMenu" and type(widget_) != type(0) \
        and widget != 'NQFormLayoutRow':
        node2widget[config['id']] = widget_
    #    widget_.setObjectName(config['id'])
    
    if widget == 'QWidget':
        widget_.setAttribute(Qt.WA_StyledBackground, True)

    # 右键菜单处理
    #if widget == 'QPushButton':
    #    widget_.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    #    widget_.customContextMenuRequested.connect(openMenu)
    if widget == 'QProgressBar':
        widget_.setValue(70)
        widget_.setTextVisible(True)
        widget_.setAlignment(QtCore.Qt.AlignCenter)

    # 属性
    if widget[0:1]=='Q' and 'properties' in config:
        for prop in config['properties']:
            value = config['properties'][prop]

            properties = get_properties(widget)
            if prop in properties:
                prop_type = properties[prop]['type']
                prop = prop.split('::')[-1]
                if prop_type == 'String':
                    eval("widget_.set"+prop+"(value)")   
                elif prop_type == 'Number':
                    if value != "":
                        n_val = int(value)
                        eval("widget_.set"+prop+"(n_val)")      
                elif prop_type == 'QPixmap':
                    if value != "":
                        n_val = QtGui.QPixmap(value)
                        eval("widget_.set"+prop+"(n_val)") 
                elif prop_type == 'Orientation':
                    if value == '0':
                        n_val = QtCore.Qt.Horizontal
                        eval("widget_.set"+prop+"(n_val)") 
                    else:
                        n_val = QtCore.Qt.Vertical
                        eval("widget_.set"+prop+"(n_val)") 
                elif prop_type == 'FileContent':
                    if value != "":
                        try:
                            with open(value, "r", encoding="UTF-8") as fp:
                                n_val = fp.read()
                                eval("widget_.set"+prop+"(n_val)") 
                        except:
                            eval("widget_.set"+prop+"(value)") 
                elif prop_type == 'QUrl':
                    if value != "":
                        n_val = QUrl.fromLocalFile(value)
                        eval("widget_.set"+prop+"(n_val)")
                elif prop_type == 'QMargins':
                    if value != "":
                        n_val = eval('['+value+']')
                        if len(n_val) == 4:
                            print('QMargins:', n_val)
                            eval("widget_.set"+prop+"(n_val[0], n_val[1], n_val[2], n_val[3])")
                elif prop_type == 'QIcon':
                    if value != "":
                        n_val = QIcon(value)
                        eval("widget_.set"+prop+"(n_val)")
    
    if 'data' in config and 'Data::BindData' in config['data']:
        data = config['data']['Data::BindData']
        try:
            if os.path.exists(data):
                # 加载文件内容
                with open(data, "r", encoding="UTF-8") as fp:
                    data = fp.read()
            print('Data:', data)
            model = to_standardItemModel(data)
            widget_.setModel(model)
        except:
            pass
    if 'data' in config and 'Data::BindText' in config['data']:
        data = config['data']['Data::BindText']
        try:
            if os.path.exists(data):
                # 加载文件内容
                with open(data, "r", encoding="UTF-8") as fp:
                    data = fp.read()
        except:
            pass
        widget_.appendPlainText(data)
        
    #if widget == "QTableView":
    #    widget_.setIndexWidget(widget_.model().index(0, 1), QW_.QPushButton("button"))

    # 针对DockWidget进行Tab合并
    #   {'Left': {'GroupId': []}}
    dockWidgets = {}

    # 子节点
    if 'children' not in config:
        return widget_

    for child in config['children']:
        child_ = makeui(child, node2widget)

        if widget in child_methods:
            add_obj = child_methods[widget]
        else:
            add_obj = child_methods['default']

        method = None
        if child['widget'] in add_obj:
            method = add_obj[child['widget']]
        else:
            # 先判断default对象中是否有对应描述
            if child['widget'] in child_methods['default']:
                method = child_methods['default'][child['widget']]
            elif 'default' in add_obj:
                method = add_obj["default"]
            else:
                method = child_methods['default']["default"]
        
        if type(method) == type(""):
            try:
                eval('widget_.'+method+'(child_)')
            except:
                print("add child widget failed!")
        else:
            method(child, widget_, child_)

        
        if child['widget'] == 'QDockWidget':
            dir_ = child['pos']['POS::DockWidgetArea']
            group_id_ = child['pos']['POS::DockGroupId']
            print("Child Dock:", dir_, group_id_)
            if dir_ not in dockWidgets:
                dockWidgets[dir_] = {}
            if group_id_ not in dockWidgets[dir_]:
                dockWidgets[dir_][group_id_] = []
            if len(dockWidgets[dir_][group_id_])>0:
                widget_.tabifyDockWidget(dockWidgets[dir_][group_id_][-1], child_)
                print("Child Dock Tabify --------------------------------")
            dockWidgets[dir_][group_id_].append(child_)
       
    return widget_

def RegWidget(widget_name, widget_properties, widget_make_child, widget_create):
    create_method[widget_name] = widget_create
    child_methods[widget_name] = widget_make_child
    controls[widget_name] = {}
    controls[widget_name]['properties'] = widget_properties
